// @Author EthanScriptOn
// @Desc
package dispatcher

import (
	"fmt"
)

// DispatcherConfig Dispatcher configuration item
type DispatcherConfig struct {
	componentsName      []DispatcherEnum
	producerConsumerMap map[DispatcherEnum]DispatcherEnum
	consumerProducerMap map[DispatcherEnum]DispatcherEnum
}

func GenerateDispatcherConfig() *DispatcherConfig {
	return &DispatcherConfig{
		componentsName:      make([]DispatcherEnum, 0),
		producerConsumerMap: make(map[DispatcherEnum]DispatcherEnum),
		consumerProducerMap: make(map[DispatcherEnum]DispatcherEnum),
	}
}

// AddComponent Add a CI, producer-consumer
func (d *DispatcherConfig) AddComponent(producerComponentName, consumerComponentName DispatcherEnum) {
	if producerComponentName != "" {
		d.componentsName = append(d.componentsName, producerComponentName)
		d.producerConsumerMap[producerComponentName] = consumerComponentName
	}
	if consumerComponentName != "" {
		d.componentsName = append(d.componentsName, consumerComponentName)
		d.consumerProducerMap[consumerComponentName] = producerComponentName
	}
}

// GetProducer Producers are acquired according to consumers
func (d *DispatcherConfig) GetProducer(consumerComponentName DispatcherEnum) (DispatcherEnum, error) {
	producerComponentName, ok := d.consumerProducerMap[consumerComponentName]
	if !ok {
		return "", fmt.Errorf("unable to find producer based on %v search", consumerComponentName)
	}
	return producerComponentName, nil
}

// GetConsumer Acquire consumers based on producers
func (d *DispatcherConfig) GetConsumer(producerComponentName DispatcherEnum) (DispatcherEnum, error) {
	consumerComponentName, ok := d.producerConsumerMap[producerComponentName]
	if !ok {
		return "", fmt.Errorf("unable to find consumer based on %v search", producerComponentName)
	}
	return consumerComponentName, nil
}
